package mkv.MyGUI;
import processing.core.*;

/**
 * This is the all encompasing and highly useful MyGUIButton class.
 * It supports many constructors, and a variety of carefully worked out drawing methods.
 */
public class MyGUIButton extends MyGUIObject {
  public String _text;
  public PImage _icon;
  private boolean fixedSize; // used when user specifies specific width/height, or there is no text
  														// otherwise textFont/textSize will be used to calculate width/height

  /* Constructors */
  public MyGUIButton(PApplet root, int x, int y) {
    super(root, x, y);
    _width = 10;
    _height = 10;
    _text = "";
    fixedSize = true;
  }

  public MyGUIButton(PApplet root, int x, int y, String text) {
    super(root, x, y);
    _text = text;
    // width/height will be calculated once font and fontSize are known from _parent.getStyle();
    fixedSize = false;
  }

  public MyGUIButton(PApplet root, int x, int y, int width, int height) {
    super(root, x, y);
    _width = width;
    _height = height;
    _text = "";
    fixedSize = true;
  }
  
  public MyGUIButton(PApplet root, int x, int y, String text, int width, int height) {
    super(root, x, y);
    _text = text;
    _width = width;
    _height = height;
    fixedSize = true;
  }

  public MyGUIButton(PApplet root, int x, int y, PImage icon) {
    super(root, x, y);
    _icon = icon;
    _width = icon.width + 2;
    _height = icon.height + 2;
    _text = "";
    fixedSize = true;
  }

  /**
   * Set the label text
   * 
   * @param label the new label
   */
  public void setLabel(String label) {
      _text = label;
  }
  
  /**
   * Set the label text with additional var for user to choose whether 
   * they want the size to automatically adjust based on the font, or to stay
   * at a fixed size, (compromising the hit check area) - but maintaining size.
   * 
   * @param label the new label
   * @param fixedSize stay at fixed width/height or dynamically adjust
   */
  public void setLabel(String label, boolean fixedSize) {
      _text = label;
      this.fixedSize = fixedSize;
  }
  
  public void mouseReleased() {
    hover = checkForHit();
    // If mouse was previous dragged/focused (boolean dragged) from this object,
    // and the mouse was released over the target (boolean hover)
    if(hover && dragged) {
      // If mouse is released over target create ActionEvent
      MyGUIActionEvent a = new MyGUIActionEvent(this, _actionCommand);
      a.sendEvent(_root);
    }
    dragged = false;
  } 
  
  // Draw methods for this object based on states
  public void drawStates() {
    // alias to shorten _style property to st
    MyGUIStyle st = _style;
    if(_style == null) {
      st = _parent.getStyle();
    } else {
      st = _style;
    }
    // set width/height if not already
    if(!fixedSize) {
      _root.textFont(st.font, st.fontSize);
      _width = PApplet.ceil(_root.textWidth(_text))+ 4 + st.padding;
      if(_width%2 == 1) _width++; // hack so that centrally drawn lines are always in the same place
      _height = st.fontSize + 2 + st.padding;
      if(_height%2 == 1) _height++; // hack so that centrally drawn lines are always in the same place
    }
    // set regularly used vars:
    final int halfw = PApplet.round((float)_width/2 + st.padding);
    final int halfh = PApplet.round((float)_height/2 + st.padding);
    // set icon vars if icon exists (duplicate check before drawing)
    int halfImgWidth = 0, halfImgHeight = 0;
    if(_icon != null) {
      halfImgWidth = PApplet.constrain(_icon.width, 2, _width-2)/2;
      halfImgHeight = PApplet.constrain(_icon.height, 2, _height-2)/2;
    }
    // set text offset (used each time text is drawn to screen)
    int textVOffset = st.fontSize/2 - st.padding/2 - 1;
    int textHOffset = 0;
    // decide on draw state
    hover = checkForHit();
    // move draw object to coordinates
    _root.pushMatrix();
    _root.translate(_x, _y);
    _root.scale(_scale);
    _root.rotate(PApplet.radians(_rotation));
    // Set default properties
    _root.rectMode(PApplet.CORNERS);
    _root.strokeWeight(st.strokeWeight);
    _root.strokeJoin(PApplet.MITER);
    _root.textFont(st.font, st.fontSize);
    _root.textAlign(PApplet.CENTER); 
    _root.imageMode(PApplet.CORNERS);
    if(isDisabled()) {
      // disabled state
      _root.stroke(st.buttonShadow);
      _root.fill(st.disabled);
      _root.rect(-halfw, -halfh, halfw, halfh);
      if(_text.length() > 0) {
        _root.fill(st.buttonText);
        //textSize(st.fontSize*0.95);
        _root.text(_text, textHOffset, textVOffset); 
      }
      if(_icon != null)
        _root.image(_icon, -halfImgWidth, -halfImgHeight, halfImgWidth, halfImgHeight);    
    } else if(dragged) {
      // drag/depressed state
      _root.stroke(st.buttonShadow);
      _root.fill(st.buttonFace);
      _root.rect(-halfw, -halfh, halfw, halfh);
      _root.stroke(st.buttonShadow);
      _root.noFill(); _root.strokeWeight((float)(st.strokeWeight*1.2));
      _root.quad(-halfw+1, -halfh+1, halfw-1, -halfh+1, halfw-1, halfh-1, -halfw+1, halfh-1);
      if(_text.length() > 0) {
        _root.fill(st.buttonText);
        //textSize(st.fontSize*0.95);
        _root.text(_text, textHOffset, textVOffset); 
      }
      if(_icon != null)
        _root.image(_icon, -halfImgWidth, -halfImgHeight, halfImgWidth, halfImgHeight); 
    } 
    else if(hover) {
      // hover state
      _root.stroke(st.buttonShadow);
      if(hasFocus()) {
        // focus and hover state
        _root.fill(st.buttonHighlight);
        _root.rect(-halfw, -halfh, halfw, halfh);
      } else {
        // plain hover
        _root.fill(st.buttonFace);
        _root.rect(-halfw, -halfh, halfw, halfh);
        _root.stroke(st.buttonHighlight);
        _root.noFill(); _root.strokeWeight((float)(st.strokeWeight*1.2));
        _root.quad(-halfw+1, -halfh+1, halfw-1, -halfh+1, halfw-1, halfh-1, -halfw+1, halfh-1);
      }
      // Text and Image are the same for both these states
      if(_text.length() > 0) {
        _root.fill(st.buttonText);
        _root.text(_text, textHOffset, textVOffset); 
      }
      if(_icon != null)
        _root.image(_icon, -halfImgWidth, -halfImgHeight, halfImgWidth, halfImgHeight); 
    } 
    else if(hasFocus()) {
      // focused default state
      _root.stroke(st.buttonShadow);
      _root.fill(st.buttonFace);
      _root.rect(-halfw, -halfh, halfw, halfh);
      _root.stroke(st.buttonHighlight);
      _root.noFill();
      // I don't trust rect() for drawing lines correctly, so here I'm using quad
      _root.quad(-halfw+1, -halfh+1, halfw-1, -halfh+1, halfw-1, halfh-1, -halfw+1, halfh-1);
      if(_text.length() > 0) {
        _root.fill(st.buttonText);
        _root.text(_text, textHOffset, textVOffset); 
      }
      if(_icon != null)
        _root.image(_icon, -halfImgWidth, -halfImgHeight, halfImgWidth, halfImgHeight); 
    } 
    else {
      // default state
      _root.stroke(st.buttonShadow);
      _root.fill(st.buttonFace);
      _root.rect(-halfw, -halfh, halfw, halfh);
      if(_text.length() > 0) {
        _root.fill(st.buttonText);
        _root.text(_text, textHOffset, textVOffset);
      }
      if(_icon != null)
        _root.image(_icon, -halfImgWidth, -halfImgHeight, halfImgWidth, halfImgHeight); 
    }
    _root.popMatrix();
  }
}
